#include <stdio.h>
#include <stdlib.h>
#include <sthread.h>
#include <block.h>
#include <assert.h>
#include "../include/logrw.h"

#define BLKSIZE 8
#define NUMBLK 40
#define NUMREGS 3

// Fills a block with "number" and "version" on its first two integers 
// positions and then writes it on position "number"
#define WRITEREGISTER(number, version) (block[0]=(char)number, block[1]=(char)version, logrw_write(lbks,number, (char *)block))
// Reads the block indexed by "number", and prints its first two positions: the "number" 
// and "version" of the block
#define READREGISTER(number) (logrw_read(lbks, number, block))


void *thread_BLKW(void * _lbks) {
	logrw_struct_t *lbks = (logrw_struct_t *)_lbks;
	int i,j;

	char *block;

	if( (block = (char *)malloc(BLKSIZE)) == NULL)
	{
	 printf("error in block malloc\n");
	 return NULL;
    }

	for (j=0;j<NUMBLK;j++)	
	 for (i=0;i<NUMREGS;i++)
          WRITEREGISTER(i,j);
      
	free(block);
	sthread_exit(NULL);
	return NULL;
}

void *thread_BLKW2(void * _lbks) {
	logrw_struct_t *lbks = (logrw_struct_t *)_lbks;
	int i,j;

	char *block;

	if( (block = (char *)malloc(BLKSIZE)) == NULL)
	{
	 printf("error in block malloc\n");
	 return NULL;
        }
	
	for (j=0;j<NUMBLK;j++)	
	 for (i=0;i<NUMREGS;i++)
           WRITEREGISTER(i,2*j);
      
	free(block);
	sthread_exit(NULL);
	return NULL;
}

void *thread_BLKR(void * _lbks) {
	logrw_struct_t *lbks = (logrw_struct_t *)_lbks;
	int i,j;

	char *block;

	if( (block = (char *)malloc(BLKSIZE)) == NULL)
	{
	 printf("error in block malloc\n");
	 return NULL;
        }
	for (j=0;j<NUMBLK;j++)	
	  for (i=0;i<NUMREGS;i++)	
           READREGISTER(i);
	free(block);
	sthread_exit(NULL);
	return NULL;
}

int main (int argc, const char * argv[]) {
    void *ret;
	int i;
	
    sthread_init();
	
    logrw_struct_t* lbks= logrw_init(NUMREGS, NUMBLK, BLKSIZE);
    sthread_t tW2 = sthread_create(thread_BLKW2, lbks, 1,1,0);
    if(tW2 == NULL){
	 printf("thread creation failed\n");
	 exit(-1);
	 }
    sthread_t tW = sthread_create(thread_BLKW, lbks, 1,1,0);
    if(tW == NULL){
	 printf("thread creation failed\n");
	 exit(-1);
	 }
    sthread_t tR = sthread_create(thread_BLKR, lbks, 1,1,0);
    if(tR == NULL){
	 printf("thread creation failed\n");
	 exit(-1);
	 }
	sthread_join(tW2, &ret);	 
	sthread_join(tW, &ret);
    sthread_join(tR, &ret);
	
    logrw_free(lbks);
    return 0;
}

